<template>
  <div class="c-weektime">
    <div class="c-schedue"></div>
    <div :class="{ 'c-schedue': true, 'c-schedue-notransi': mode }"
         :style="{width:`${region.width}px`
         ,height: `${region.height}px`
         ,left: `${region.left}px`
         ,top: `${region.top}px`}"/>
    <table class="c-weektime-table">
      <thead class="c-weektime-head">
      <tr>
        <th rowspan="8" class="week-td">W/T</th>
        <th :colspan="12">凌晨</th>
        <th :colspan="12">上午</th>
        <th :colspan="12">下午</th>
        <th :colspan="12">夜间</th>
      </tr>
      <tr><td v-for="t in theadArr" :key="t" :colspan="2">{{ t }}</td></tr>
      </thead>
      <tbody class="c-weektime-body">
      <tr v-for="t in data" :key="t.row">
        <td>{{ t.value }}</td>
        <td v-for="n in t.child"
            :key="`${n.row}-${n.col}`"
            :row="n.row"
            :col="n.col"
            @mouseenter="cellEnter(n)"
            @mousedown="cellDown(n)"
            @mouseup="cellUp(n)"
            :class="selectClasses(n)"
            class="weektime-atom-item"></td>
      </tr>
      <tr>
        <td colspan="49" class="c-weektime-preview">
          <div class="g-clearfix c-weektime-con">
            <a class="g-pull-right" @click.prevent="clear">清空选择</a>
          </div>
        </td>
      </tr>
      </tbody>
    </table>
  </div>
</template>
<script>
import { defineEmits } from 'vue'
const createArr = (len) => {
  return Array.from(Array(len)).map((ret, id) => id);
};
export default {
  name: "DragWeektime",
  props: {
    modelValue: {
      type: Array,
      default: []
    }
  },
  setup(props,context) {
    //const emit = defineEmits(['update:modelValue']);
    const createArr = (len) => {
      return Array.from(Array(len)).map((ret, id) => id);
    };
    const getTimeStr = (num) =>{
      const totalMinutes = num * 30;
      const hours = Math.floor(totalMinutes / 60)>23?0: Math.floor(totalMinutes / 60);
      const minutes = totalMinutes % 60;
      return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`;
    }

    const getTimeIndex = (timeStr) =>{
      const [hours, minutes] = timeStr.split(':').map(Number);
      const totalMinutes = hours * 60 + minutes;
      return totalMinutes / 30;
    }

    const theadArr = createArr(24)
    const allWeeks = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
    const data = ref(allWeeks.map((item,index)=>{return {value:item, child:Array.from({ length:48 }, (v,k) => {return {s:getTimeStr(k),e:getTimeStr(k+1),row:index,
        col: k,check:false}})}}))
    //回显
    if(props.modelValue){
      props.modelValue.forEach(item=>{
        const week = data.value[item.id];
        item.values.forEach(p=>{
          const begin = getTimeIndex(p.s);
          const end = p.e==='00:00'?47:getTimeIndex(p.e)-1;
          week.child.forEach((dt,index)=>{
              dt.check = index>=begin&&index<=end;
          });
        })
      })
    }


    const mode = ref(false)
    const region=reactive({width: 0, height: 0, left: 0, top: 0})
    const points=reactive({x1: 0, x2: 0, y1: 0, y2: 0})
    const startEl = ref(null);
    const endEl = ref(null);
    const check = ref(true);
    const cellDown = (n)=>{
      startEl.value = document.querySelector(`td[row='${n.row}'][col='${n.col}']`);
      points.x1 = parseInt(startEl.value.getAttribute('row'));
      points.y1 = parseInt(startEl.value.getAttribute('col'));
      check.value = n.check;
      mode.value =true;
      cellEnter(n)
    }

    const cellEnter=(n)=>{
      endEl.value = document.querySelector(`td[row='${n.row}'][col='${n.col}']`);
      if(!mode.value&&endEl){
        region.top = endEl.value.offsetTop;
        region.left = endEl.value.offsetLeft;
      }else if(mode.value) {
        points.x2 = parseInt(endEl.value.getAttribute('row'));
        points.y2 = parseInt(endEl.value.getAttribute('col'));
        region.top = points.x1 < points.x2 ? startEl.value.offsetTop : endEl.value.offsetTop;
        region.left = points.y1 < points.y2 ? startEl.value.offsetLeft : endEl.value.offsetLeft;
        region.width = startEl.value.offsetWidth * (Math.abs(points.y2 - points.y1) + 1);
        region.height = startEl.value.offsetHeight * (Math.abs(points.x2 - points.x1) + 1);
      }
    }
    const cellUp=(n)=>{
      const maxRow = points.x2>points.x1?points.x2:points.x1;
      const minRow = points.x2>points.x1?points.x1:points.x2;
      const maxCol = points.y2>points.y1?points.y2:points.y1;
      const minCol = points.y2>points.y1?points.y1:points.y2;
      selectWeek([minRow, maxRow], [minCol, maxCol],!check.value);
      mode.value =false;
      region.width = 0;
      region.height=0;
    }
    const selectClasses=(n)=>{
      return n.check ? "ui-selected" : "";
    }

    const setValue = ()=>{
      const result = [];
      data.value.forEach((week,index)=>{
        const list = week.child;
        const values = [];
        let some = false;
        list.forEach(item=>{
          if(!item.check){
            some = false;
            return;
          }
          if(!some){
            values.push({s:item.s,e:item.e})
            some = true;
          }else{
            values[values.length-1].e = item.e;
          }
        })
        if(values.length>0){
          result.push({id:index,values:values});
        }
      })
      context.emit('update:modelValue',result);
    }



    const selectWeek = (row, col, check)=>{
      const [minRow, maxRow] = row;
      const [minCol, maxCol] = col;
      data.value.forEach((item) => {
        item.child.forEach((t) => {
          if (t.row >= minRow && t.row <= maxRow && t.col >= minCol && t.col <= maxCol) {
            t.check =check;
          }
        });
      });
      setValue();
    }



    const clear = ()=>{
      data.value.forEach((item) => {
        item.child.forEach((t) => {
            t.check=false;
        });
      });
    }
    return {theadArr,data,mode,cellEnter,cellUp,selectClasses,cellDown,region,clear}
  }
}
</script>
<style scoped>
.c-weektime {

  position: relative;
  display: inline-block;
}

.c-schedue {
  background: #598fe6;
  position: absolute;
  width: 0;
  height: 0;
  opacity: 0.6;
  pointer-events: none;
}

.c-schedue-notransi {
  transition: width 0.12s ease, height 0.12s ease, top 0.12s ease, left 0.12s ease;
}

.c-weektime-table {
  border-collapse: collapse;
}
.c-weektime-table th {
  vertical-align: inherit;
  font-weight: bold;
}
.c-weektime-table tr {
  height: 26px;
}
.c-weektime-table tr,
.c-weektime-table td,
.c-weektime-table th {
  user-select: none;
  border: 1px solid #dee4f5;
  text-align: center;
  min-width: 12px;
  line-height: 1.8em;
  transition: background 0.2s ease;
}
.c-weektime-table .c-weektime-head {
  font-size: 12px;
}
.c-weektime-table .c-weektime-head .week-td {
  width: 70px;
}
.c-weektime-table .c-weektime-body {
  font-size: 12px;
}
.c-weektime-table .c-weektime-body td.weektime-atom-item {
  user-select: unset;
  background-color: #f5f5f5;
}
.c-weektime-table .c-weektime-body td.ui-selected {
  background-color: #598fe6;
}
.c-weektime-table .c-weektime-preview {
  line-height: 2.4em;
  padding: 0 10px;
  font-size: 14px;
}
.c-weektime-table .c-weektime-preview .c-weektime-con {
  line-height: 46px;
  user-select: none;
}
.c-weektime-table .c-weektime-preview .c-weektime-time {
  text-align: left;
  line-height: 2.4em;
}
.c-weektime-table .c-weektime-preview .c-weektime-time p {
  max-width: 625px;
  line-height: 1.4em;
  word-break: break-all;
  margin-bottom: 8px;
}

.c-min-table tr,
.c-min-table td,
.c-min-table th {
  min-width: 24px;
}

.g-clearfix:after, .g-clearfix:before {
  clear: both;
  content: " ";
  display: table;
}

.g-pull-left {
  float: left;
}

.g-pull-right {
  float: right;
}

.g-tip-text {
  color: #999;
}
</style>